﻿//-----------------------------------------------------------------------
// <copyright file="Search.cs" company="Microsoft Corporation">
//     Copyright Microsoft Corporation. All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) This is sample code only, do not use in production environments.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp.ViewModels
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp.Models;
    using Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp.MVVMSupport;
    using Windows.ApplicationModel.DataTransfer;

    /// <summary>
    /// View Model for the search page.
    /// </summary>
    public class Search : IShare
    {
        /// <summary>
        /// Initializes a new instance of the Search class.
        /// </summary>
        /// <param name="query">the query to match guidance and categories on</param>
        public Search(string query)
        {
            this.GoToHome = new Command(() =>
            {
                Navigation.Navigate(typeof(Views.TreasureMapPage));
            });

            this.GoBack = new Command(() =>
            {
                if (Navigation.CanGoBack)
                {
                    Navigation.GoBack();
                }
                else
                {
                    Navigation.Navigate(typeof(Views.TreasureMapPage));
                }
            });

            this.Categories = new ObservableCollection<Models.Category>();
            this.Projects = new ObservableCollection<Models.Project>();

            this.SearchContent(query);

            DataTransferManager.GetForCurrentView().DataRequested += this.Search_DataRequested;
        }

        /// <summary>
        /// Gets the command to go back.
        /// </summary>
        public Command GoBack { get; private set; }

        /// <summary>
        /// Gets the command to go home.
        /// </summary>
        public Command GoToHome { get; private set; }

        /// <summary>
        /// Gets or sets the Categories collection.
        /// </summary>
        public ObservableCollection<Models.Category> Categories { get; set; }

        /// <summary>
        /// Gets or sets the Guidance collection.
        /// </summary>
        public ObservableCollection<Models.Project> Projects { get; set; }

        /// <summary>
        /// Gets or sets the selected Category property
        /// What this really does is returns null to a property bound to it
        /// however when this property is set (on an item selected event, same as an item clicked event)
        /// the set is called, which makes a call to navigate.
        /// This is used as a slick alternative to creating an attached dependency property of type ICommand
        /// as it uses the an unused property.  Binding null does not throw an exception.
        /// </summary>
        public Models.Category SelectedCategory
        {
            get
            {
                return null;
            }

            set
            {
                Navigation.Navigate(typeof(Views.Projects), value.Id);
            }
        }

        /// <summary>
        /// Gets or sets the selected guidance property
        /// What this really does is returns null to a property bound to it
        /// however when this property is set (on an item selected event, same as an item clicked event)
        /// the set is called, which makes a call to navigate.
        /// This is used as a slick alternative to creating an attached dependency property of type ICommand
        /// as it uses the an unused property.  Binding null does not throw an exception.
        /// </summary>
        public Models.Project SelectedProject
        {
            get
            {
                return null;
            }

            set
            {
                var input = Tuple.Create(value.Category, value);

                Navigation.Navigate(typeof(Views.Projects), input);
            }
        }

        /// <summary>
        /// Event handler for a share query.
        /// </summary>
        /// <param name="sender">The parameter is not used.</param>
        /// <param name="args">The parameter is not used.</param>
        public void Search_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
        {
            args.Request.FailWithDisplayText("Nothing can be shared on this page, but other pages do have treasure that can be shared! Happy exploring!");
        }

        /// <summary>
        /// Deregisters the share event handler.
        /// </summary>
        public void Deregister()
        {
            DataTransferManager.GetForCurrentView().DataRequested -= this.Search_DataRequested;
        }

        /// <summary>
        /// Sets the data context of the page based on the search query.
        /// </summary>
        /// <param name="query">String to match categories and guidance to.</param>
        public void SearchContent(string query)
        {
            this.Categories.Clear();
            this.Projects.Clear();

            foreach (var category in App.Database.Categories)
            {
                if (category.Name.IndexOf(query, StringComparison.CurrentCultureIgnoreCase) >= 0)
                {
                    this.Categories.Add(category);
                }

                foreach (var project in category.Projects)
                {
                    if (project.Description.IndexOf(query, StringComparison.CurrentCultureIgnoreCase) >= 0 ||
                        project.Name.IndexOf(query, StringComparison.CurrentCultureIgnoreCase) >= 0)
                    {                                                                                       
                        this.Projects.Add(project);
                    }
                }
            }
        }
    }
}
